package com.rc.web.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowUtil;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.rc.common.constant.Code;
import com.rc.common.exception.BusinessException;
import com.rc.pojo.dto.plantItem.PlantItemAddDTO;
import com.rc.pojo.dto.plantItem.PlantItemQuery;
import com.rc.pojo.dto.plantItem.PlantItemUpdateDTO;
import com.rc.pojo.po.PlantItem;
import com.rc.pojo.vo.plantitem.PlantItemDetailVO;
import com.rc.pojo.vo.plantitem.PlantItemPageVO;
import com.rc.pojo.vo.plantitem.PlantItemVO;
import com.rc.web.mapper.PlantItemMapper;
import com.rc.web.service.MaintenanceService;
import com.rc.web.service.PlantItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 植物项服务实现类
 * 提供植物项相关的业务逻辑实现
 */
@Service
@RequiredArgsConstructor
public class PlantItemServiceImpl extends ServiceImpl<PlantItemMapper, PlantItem> implements PlantItemService {
    // 养护服务
    private final MaintenanceService maintenanceService;

    /**
     * 获取植物项详情
     * @param id 植物项ID
     * @return 植物项详情VO
     */
    @Override
    public PlantItemDetailVO getDetail(Long id) {
        Row row = mapper.selectDetail(id);
        return RowUtil.toObject(row, PlantItemDetailVO.class);
    }

    /**
     * 认养植物项
     * @param plantId 植物ID
     * @return 被认养的植物项
     */
    @Override
    public PlantItem adoption(Long plantId) {
        // 根据植物ID获取植物项列表
        List<PlantItem> plantItemList = mapper.selectByPlantId(plantId);

        // 找到未被认养的植物项
        PlantItem plantItem = plantItemList
                .stream()
                .filter(item -> !item.getAdoption())
                .findFirst()
                .orElseThrow(() -> new BusinessException(Code.NO_TREE));

        // 标记为已认养并更新
        plantItem.setAdoption(true);
        this.updateById(plantItem);
        return plantItem;
    }

    /**
     * 分页查询植物项
     * @param query 查询条件
     * @return 分页结果
     */
    @Override
    public Page<PlantItemPageVO> getPage(PlantItemQuery query) {
        return mapper.selectPage(query);
    }

    /**
     * 添加植物项
     * @param dto 植物项添加DTO
     */
    @Override
    public void add(PlantItemAddDTO dto) {
        // 构建植物项对象并保存
        PlantItem planItem = PlantItem.builder()
                .name(dto.getName())
                .areaId(dto.getAreaId())
                .adoption(dto.getAdoption())
                .cover(dto.getCover())
                .ills(dto.getIlls())
                .ripe_num(dto.getRipe_num())
                .build();
        this.save(planItem);
    }

    /**
     * 根据ID获取植物项
     * @param id 植物项ID
     * @return 植物项VO
     */
    @Override
    public PlantItemVO getOneById(Long id) {
        PlantItem item = this.getById(id);
        return PlantItemVO.builder()
                .name(item.getName())
                .areaId(item.getAreaId())
                .id(item.getId())
                .adoption(item.getAdoption())
                .cover(item.getCover())
                .ills(item.getIlls())
                .ripe_num(item.getRipe_num())
                .description(item.getDescription())
                .build();
    }

    /**
     * 根据ID删除植物项
     * @param id 植物项ID
     */
    @Override
    public void deleteOneById(Long id) {
        PlantItem item = this.getById(id);

        // 检查是否已被认养
        if (item.getAdoption()){
            throw new BusinessException(Code.TREE_HAS_ADOPTION);
        }

        // 删除植物项
        this.removeById(id);
    }

    /**
     * 更新植物项
     * @param dto 植物项更新DTO
     */
    @Override
    public void updateOneById(PlantItemUpdateDTO dto) {
        PlantItem item = this.getById(dto.getId());

        // 合并病虫害列表并去重
        List<String> ills = item.getIlls();
        ills.addAll(dto.getIlls());
        item.setIlls(ills.stream().distinct().toList());

        // 更新其他字段
        item.setCover(dto.getCover());
        item.setAdoption(dto.getAdoption());
        item.setRipe_num(dto.getRipe_num());
        item.setAreaId(dto.getAreaId());
        item.setDescription(dto.getDescription());
        item.setName(dto.getName());

        // 保存更新
        this.updateById(item);
    }
}
